using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace WPFTemplateLib.Attached
{
    /// <summary>
    /// RadioButton 附加属性类
    /// </summary>
    public class RadioButtonAttached : DependencyObject
    {
        #region IsCanUncheck（是否可取消选中）

        public static bool GetIsCanUncheck(FrameworkElement item)
        {
            return (bool)item.GetValue(IsCanUncheckProperty);
        }

        public static void SetIsCanUncheck(FrameworkElement item, bool value)
        {
            item.SetValue(IsCanUncheckProperty, value);
        }

        /// <summary>
        /// 是否能取消选中
        /// </summary>
        public static readonly DependencyProperty IsCanUncheckProperty =
            DependencyProperty.RegisterAttached(
                "IsCanUncheck",
                typeof(bool),
                typeof(RadioButtonAttached),
                new UIPropertyMetadata(false, OnIsCanUncheckChanged));

        static void OnIsCanUncheckChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
        {
            FrameworkElement item = depObj as FrameworkElement;

            if (item == null)
                return;

            switch (depObj)
            {
                case RadioButton radioButton:
                {
                    if ((bool)e.NewValue)
                    {
                        radioButton.PreviewMouseDown += RadioButton_PreviewMouseDown;
                    }
                    else
                    {
                        radioButton.PreviewMouseDown -= RadioButton_PreviewMouseDown;
                    }
                    break;
                }
                default:
                    break;
            }
        }

        private static void RadioButton_PreviewMouseDown(object sender, RoutedEventArgs e)
        {
            var rb = sender as RadioButton;
            if (rb == null)
            {
                return;
            }

            if (rb.IsChecked == true)
            {
                rb.IsChecked = false;
                e.Handled = true;
            }
        }

		#endregion

		#region 绑定选中值

		//https://stackoverflow.org.cn/questions/1317891

		[AttachedPropertyBrowsableForType(typeof(RadioButton))]
		public static object GetRadioValue(DependencyObject obj) => obj.GetValue(RadioValueProperty);
		public static void SetRadioValue(DependencyObject obj, object value) => obj.SetValue(RadioValueProperty, value);
		public static readonly DependencyProperty RadioValueProperty =
			DependencyProperty.RegisterAttached("RadioValue", typeof(object), typeof(RadioButtonAttached), new PropertyMetadata(OnRadioValueChanged));
		private static void OnRadioValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			if(d is RadioButton rb)
			{
				rb.Checked -= OnChecked;
				rb.Checked += OnChecked;
			}
		}

		public static void OnChecked(object sender, RoutedEventArgs e)
		{
			if(sender is RadioButton rb)
			{
				rb.SetCurrentValue(RadioBindingProperty, rb.GetValue(RadioValueProperty));
			}
		}

		[AttachedPropertyBrowsableForType(typeof(RadioButton))]
		public static object GetRadioBinding(DependencyObject obj) => obj.GetValue(RadioBindingProperty);
		/// <summary>
		/// 设置 选中值绑定
		/// </summary>
		public static void SetRadioBinding(DependencyObject obj, object value) => obj.SetValue(RadioBindingProperty, value);
		public static readonly DependencyProperty RadioBindingProperty =
			DependencyProperty.RegisterAttached("RadioBinding", typeof(object), typeof(RadioButtonAttached), 
				new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnRadioBindingChanged));
		private static void OnRadioBindingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			RadioButton rb = d as RadioButton;
			if(rb == null)
				return;

			if(rb.GetValue(RadioValueProperty).Equals(e.NewValue))
			{
				rb.SetCurrentValue(RadioButton.IsCheckedProperty, true);
			}
			else
			{
				rb.SetCurrentValue(RadioButton.IsCheckedProperty, false);
			}
		}

		#endregion

		#region 附加属性（样式设置）

		#region [附加属性] 边框圆角（默认0）
		public static CornerRadius GetCornerRadius(DependencyObject obj)
		{
			return (CornerRadius)obj.GetValue(CornerRadiusProperty);
		}
		/// <summary>
		/// 设置 边框圆角（默认0）
		/// </summary>
		public static void SetCornerRadius(DependencyObject obj, CornerRadius value)
		{
			obj.SetValue(CornerRadiusProperty, value);
		}
		/// <summary>
		/// [附加属性] 边框圆角（默认0）
		/// </summary>
		public static readonly DependencyProperty CornerRadiusProperty =
			DependencyProperty.RegisterAttached("CornerRadius", typeof(CornerRadius), typeof(RadioButtonAttached), new PropertyMetadata(new CornerRadius(0)));
		#endregion

		#region [附加属性] 固定部分边距(默认5,0,0,0)
		public static Thickness GetFixPartMargin(DependencyObject obj)
		{
			return (Thickness)obj.GetValue(FixPartMarginProperty);
		}
		/// <summary>
		/// 设置 固定部分边距(默认5,0,0,0)
		/// </summary>
		public static void SetFixPartMargin(DependencyObject obj, Thickness value)
		{
			obj.SetValue(FixPartMarginProperty, value);
		}
		/// <summary>
		/// [附加属性] 固定部分边距(默认5,0,0,0)
		/// </summary>
		public static readonly DependencyProperty FixPartMarginProperty =
			DependencyProperty.RegisterAttached("FixPartMargin", typeof(Thickness), typeof(RadioButtonAttached), new PropertyMetadata(new Thickness(5,0,0,0)));
		#endregion

		#region [附加属性] 固定部分水平对齐方式（默认居中）
		public static HorizontalAlignment GetFixPartHorizontalAlignment(DependencyObject obj)
		{
			return (HorizontalAlignment)obj.GetValue(FixPartHorizontalAlignmentProperty);
		}
		/// <summary>
		/// 设置 固定部分水平对齐方式（默认居中）
		/// </summary>
		public static void SetFixPartHorizontalAlignment(DependencyObject obj, HorizontalAlignment value)
		{
			obj.SetValue(FixPartHorizontalAlignmentProperty, value);
		}
		/// <summary>
		/// [附加属性] 固定部分水平对齐方式（默认居中）
		/// </summary>
		public static readonly DependencyProperty FixPartHorizontalAlignmentProperty =
			DependencyProperty.RegisterAttached("FixPartHorizontalAlignment", typeof(HorizontalAlignment), typeof(RadioButtonAttached), new PropertyMetadata(HorizontalAlignment.Center));
		#endregion

		#region [附加属性] 固定部分垂直对齐方式（默认居中）
		public static VerticalAlignment GetFixPartVerticalAlignment(DependencyObject obj)
		{
			return (VerticalAlignment)obj.GetValue(FixPartVerticalAlignmentProperty);
		}
		/// <summary>
		/// 设置 固定部分垂直对齐方式（默认居中）
		/// </summary>
		public static void SetFixPartVerticalAlignment(DependencyObject obj, VerticalAlignment value)
		{
			obj.SetValue(FixPartVerticalAlignmentProperty, value);
		}
		/// <summary>
		/// [附加属性] 固定部分垂直对齐方式（默认居中）
		/// </summary>
		public static readonly DependencyProperty FixPartVerticalAlignmentProperty =
			DependencyProperty.RegisterAttached("FixPartVerticalAlignment", typeof(VerticalAlignment), typeof(RadioButtonAttached), new PropertyMetadata(VerticalAlignment.Center));
		#endregion

		#region [附加属性] 内容部分边距(默认5,0,5,0)
		public static Thickness GetContentPartMargin(DependencyObject obj)
		{
			return (Thickness)obj.GetValue(ContentPartMarginProperty);
		}
		/// <summary>
		/// 设置 内容部分边距(默认5,0,5,0)
		/// </summary>
		public static void SetContentPartMargin(DependencyObject obj, Thickness value)
		{
			obj.SetValue(ContentPartMarginProperty, value);
		}
		/// <summary>
		/// [附加属性] 内容部分边距(默认5,0,5,0)
		/// </summary>
		public static readonly DependencyProperty ContentPartMarginProperty =
			DependencyProperty.RegisterAttached("ContentPartMargin", typeof(Thickness), typeof(RadioButtonAttached), new PropertyMetadata(new Thickness(5,0,5,0)));
		#endregion

		#region [附加属性] 内容部分水平对齐方式（默认居中）
		public static HorizontalAlignment GetContentPartHorizontalAlignment(DependencyObject obj)
		{
			return (HorizontalAlignment)obj.GetValue(ContentPartHorizontalAlignmentProperty);
		}
		/// <summary>
		/// 设置 内容部分水平对齐方式（默认居中）
		/// </summary>
		public static void SetContentPartHorizontalAlignment(DependencyObject obj, HorizontalAlignment value)
		{
			obj.SetValue(ContentPartHorizontalAlignmentProperty, value);
		}
		/// <summary>
		/// [附加属性] 内容部分水平对齐方式（默认居中）
		/// </summary>
		public static readonly DependencyProperty ContentPartHorizontalAlignmentProperty =
			DependencyProperty.RegisterAttached("ContentPartHorizontalAlignment", typeof(HorizontalAlignment), typeof(RadioButtonAttached), new PropertyMetadata(HorizontalAlignment.Center));
		#endregion

		#region [附加属性] 内容部分垂直对齐方式（默认居中）
		public static VerticalAlignment GetContentPartVerticalAlignment(DependencyObject obj)
		{
			return (VerticalAlignment)obj.GetValue(ContentPartVerticalAlignmentProperty);
		}
		/// <summary>
		/// 设置 内容部分垂直对齐方式（默认居中）
		/// </summary>
		public static void SetContentPartVerticalAlignment(DependencyObject obj, VerticalAlignment value)
		{
			obj.SetValue(ContentPartVerticalAlignmentProperty, value);
		}
		/// <summary>
		/// [附加属性] 内容部分垂直对齐方式（默认居中）
		/// </summary>
		public static readonly DependencyProperty ContentPartVerticalAlignmentProperty =
			DependencyProperty.RegisterAttached("ContentPartVerticalAlignment", typeof(VerticalAlignment), typeof(RadioButtonAttached), new PropertyMetadata(VerticalAlignment.Center));
		#endregion

		#region [附加属性] 外部圆圈直径（默认20）
		public static double GetOuterCircleDiameter(DependencyObject obj)
		{
			return (double)obj.GetValue(OuterCircleDiameterProperty);
		}
		/// <summary>
		/// 设置 外部圆圈直径（默认20）
		/// </summary>
		public static void SetOuterCircleDiameter(DependencyObject obj, double value)
		{
			obj.SetValue(OuterCircleDiameterProperty, value);
		}
		/// <summary>
		/// [附加属性] 外部圆圈直径（默认20）
		/// </summary>
		public static readonly DependencyProperty OuterCircleDiameterProperty =
			DependencyProperty.RegisterAttached("OuterCircleDiameter", typeof(double), typeof(RadioButtonAttached), new PropertyMetadata(20d));
		#endregion

		#region [附加属性] 内部圆圈直径（默认14）
		public static double GetInnerCircleDiameter(DependencyObject obj)
		{
			return (double)obj.GetValue(InnerCircleDiameterProperty);
		}
		/// <summary>
		/// 设置 内部圆圈直径（默认14）
		/// </summary>
		public static void SetInnerCircleDiameter(DependencyObject obj, double value)
		{
			obj.SetValue(InnerCircleDiameterProperty, value);
		}
		/// <summary>
		/// [附加属性] 内部圆圈直径（默认14）
		/// </summary>
		public static readonly DependencyProperty InnerCircleDiameterProperty =
			DependencyProperty.RegisterAttached("InnerCircleDiameter", typeof(double), typeof(RadioButtonAttached), new PropertyMetadata(14d));
		#endregion

		#region [附加属性] 外部圆圈边框颜色
		public static Brush GetOuterCircleBorderBrush(DependencyObject obj)
		{
			return (Brush)obj.GetValue(OuterCircleBorderBrushProperty);
		}
		/// <summary>
		/// 设置 外部圆圈边框颜色
		/// </summary>
		public static void SetOuterCircleBorderBrush(DependencyObject obj, Brush value)
		{
			obj.SetValue(OuterCircleBorderBrushProperty, value);
		}
		/// <summary>
		/// [附加属性] 外部圆圈边框颜色
		/// </summary>
		public static readonly DependencyProperty OuterCircleBorderBrushProperty =
			DependencyProperty.RegisterAttached("OuterCircleBorderBrush", typeof(Brush), typeof(RadioButtonAttached), new PropertyMetadata(new SolidColorBrush(Colors.DimGray)));
		#endregion

		#region [附加属性] 外圈圆圈边框颜色（勾选时）
		public static Brush GetOuterCircleCheckedBorderBrush(DependencyObject obj)
		{
			return (Brush)obj.GetValue(OuterCircleCheckedBorderBrushProperty);
		}
		/// <summary>
		/// 设置 外圈圆圈边框颜色（勾选时）
		/// </summary>
		public static void SetOuterCircleCheckedBorderBrush(DependencyObject obj, Brush value)
		{
			obj.SetValue(OuterCircleCheckedBorderBrushProperty, value);
		}
		/// <summary>
		/// [附加属性] 外圈圆圈边框颜色（勾选时）
		/// </summary>
		public static readonly DependencyProperty OuterCircleCheckedBorderBrushProperty =
			DependencyProperty.RegisterAttached("OuterCircleCheckedBorderBrush", typeof(Brush), typeof(RadioButtonAttached), new PropertyMetadata(new SolidColorBrush(Colors.DodgerBlue)));
		#endregion

		#region [附加属性] 外部圆圈边框粗细
		public static Thickness GetOuterCircleBorderThickness(DependencyObject obj)
		{
			return (Thickness)obj.GetValue(OuterCircleBorderThicknessProperty);
		}
		/// <summary>
		/// 设置 外部圆圈边框粗细
		/// </summary>
		public static void SetOuterCircleBorderThickness(DependencyObject obj, Thickness value)
		{
			obj.SetValue(OuterCircleBorderThicknessProperty, value);
		}
		/// <summary>
		/// [附加属性] 外部圆圈边框粗细
		/// </summary>
		public static readonly DependencyProperty OuterCircleBorderThicknessProperty =
			DependencyProperty.RegisterAttached("OuterCircleBorderThickness", typeof(Thickness), typeof(RadioButtonAttached), new PropertyMetadata(new Thickness(1)));
		#endregion

		#region [附加属性] 外圈圆圈填充颜色（默认透明）
		public static Brush GetOuterCircleFillBrush(DependencyObject obj)
		{
			return (Brush)obj.GetValue(OuterCircleFillBrushProperty);
		}
		/// <summary>
		/// 设置 外圈圆圈填充颜色（默认透明）
		/// </summary>
		public static void SetOuterCircleFillBrush(DependencyObject obj, Brush value)
		{
			obj.SetValue(OuterCircleFillBrushProperty, value);
		}
		/// <summary>
		/// [附加属性] 外圈圆圈填充颜色（默认透明）
		/// </summary>
		public static readonly DependencyProperty OuterCircleFillBrushProperty =
			DependencyProperty.RegisterAttached("OuterCircleFillBrush", typeof(Brush), typeof(RadioButtonAttached), new PropertyMetadata(new SolidColorBrush(Colors.Transparent)));
		#endregion

		#region [附加属性] 内圈圆圈填充颜色
		public static Brush GetInnerCircleFillBrush(DependencyObject obj)
		{
			return (Brush)obj.GetValue(InnerCircleFillBrushProperty);
		}
		/// <summary>
		/// 设置 内圈圆圈填充颜色
		/// </summary>
		public static void SetInnerCircleFillBrush(DependencyObject obj, Brush value)
		{
			obj.SetValue(InnerCircleFillBrushProperty, value);
		}
		/// <summary>
		/// [附加属性] 内圈圆圈填充颜色
		/// </summary>
		public static readonly DependencyProperty InnerCircleFillBrushProperty =
			DependencyProperty.RegisterAttached("InnerCircleFillBrush", typeof(Brush), typeof(RadioButtonAttached), new PropertyMetadata(new SolidColorBrush(Colors.DodgerBlue)));
		#endregion

		#region [附加属性] 选中时的文字颜色(前景色)
		public static Brush GetCheckedForeground(DependencyObject obj)
		{
			return (Brush)obj.GetValue(CheckedForegroundProperty);
		}
		/// <summary>
		/// 设置 选中时的文字颜色(前景色)
		/// </summary>
		public static void SetCheckedForeground(DependencyObject obj, Brush value)
		{
			obj.SetValue(CheckedForegroundProperty, value);
		}
		/// <summary>
		/// [附加属性] 选中时的文字颜色(前景色)
		/// </summary>
		public static readonly DependencyProperty CheckedForegroundProperty =
			DependencyProperty.RegisterAttached("CheckedForeground", typeof(Brush), typeof(RadioButtonAttached), new PropertyMetadata(new SolidColorBrush(Colors.DodgerBlue)));
		#endregion

		#region [附加属性] 选中时的背景色
		public static Brush GetCheckedBackground(DependencyObject obj)
		{
			return (Brush)obj.GetValue(CheckedBackgroundProperty);
		}
		/// <summary>
		/// 设置 选中时的背景色
		/// </summary>
		public static void SetCheckedBackground(DependencyObject obj, Brush value)
		{
			obj.SetValue(CheckedBackgroundProperty, value);
		}
		/// <summary>
		/// [附加属性] 选中时的背景色
		/// </summary>
		public static readonly DependencyProperty CheckedBackgroundProperty =
			DependencyProperty.RegisterAttached("CheckedBackground", typeof(Brush), typeof(RadioButtonAttached), new PropertyMetadata(new SolidColorBrush(Colors.White)));
		#endregion

		#region [附加属性] 选中时的边框画刷
		public static Brush GetCheckedBorderBrush(DependencyObject obj)
		{
			return (Brush)obj.GetValue(CheckedBorderBrushProperty);
		}
		/// <summary>
		/// 设置 选中时的边框画刷
		/// </summary>
		public static void SetCheckedBorderBrush(DependencyObject obj, Brush value)
		{
			obj.SetValue(CheckedBorderBrushProperty, value);
		}
		/// <summary>
		/// [附加属性] 选中时的边框画刷
		/// </summary>
		public static readonly DependencyProperty CheckedBorderBrushProperty =
			DependencyProperty.RegisterAttached("CheckedBorderBrush", typeof(Brush), typeof(RadioButtonAttached));
		#endregion

		#region [附加属性] 选中时的边框粗细(默认1)
		public static Thickness GetCheckedBorderThickness(DependencyObject obj)
		{
			return (Thickness)obj.GetValue(CheckedBorderThicknessProperty);
		}
		/// <summary>
		/// 设置 选中时的边框粗细(默认1)
		/// </summary>
		public static void SetCheckedBorderThickness(DependencyObject obj, Thickness value)
		{
			obj.SetValue(CheckedBorderThicknessProperty, value);
		}
		/// <summary>
		/// [附加属性] 选中时的边框粗细(默认1)
		/// </summary>
		public static readonly DependencyProperty CheckedBorderThicknessProperty =
			DependencyProperty.RegisterAttached("CheckedBorderThickness", typeof(Thickness), typeof(RadioButtonAttached), new PropertyMetadata(new Thickness(1)));
		#endregion

		#region [附加属性] 鼠标移上时的文字颜色(前景色)
		public static Brush GetMouseOverForeground(DependencyObject obj)
		{
			return (Brush)obj.GetValue(MouseOverForegroundProperty);
		}
		/// <summary>
		/// 设置 鼠标移上时的文字颜色(前景色)
		/// </summary>
		public static void SetMouseOverForeground(DependencyObject obj, Brush value)
		{
			obj.SetValue(MouseOverForegroundProperty, value);
		}
		/// <summary>
		/// [附加属性] 鼠标移上时的文字颜色(前景色)
		/// </summary>
		public static readonly DependencyProperty MouseOverForegroundProperty =
			DependencyProperty.RegisterAttached("MouseOverForeground", typeof(Brush), typeof(RadioButtonAttached), new PropertyMetadata(new SolidColorBrush(Colors.DodgerBlue)));
		#endregion

		#region [附加属性] 鼠标移上时的背景色
		public static Brush GetMouseOverBackground(DependencyObject obj)
		{
			return (Brush)obj.GetValue(MouseOverBackgroundProperty);
		}
		/// <summary>
		/// 设置 鼠标移上时的背景色
		/// </summary>
		public static void SetMouseOverBackground(DependencyObject obj, Brush value)
		{
			obj.SetValue(MouseOverBackgroundProperty, value);
		}
		/// <summary>
		/// [附加属性] 鼠标移上时的背景色
		/// </summary>
		public static readonly DependencyProperty MouseOverBackgroundProperty =
			DependencyProperty.RegisterAttached("MouseOverBackground", typeof(Brush), typeof(RadioButtonAttached), new PropertyMetadata(new SolidColorBrush(Colors.LightBlue)));
		#endregion

		#region [附加属性] 鼠标移上时的边框画刷
		public static Brush GetMouseOverBorderBrush(DependencyObject obj)
		{
			return (Brush)obj.GetValue(MouseOverBorderBrushProperty);
		}
		/// <summary>
		/// 设置 鼠标移上时的边框画刷
		/// </summary>
		public static void SetMouseOverBorderBrush(DependencyObject obj, Brush value)
		{
			obj.SetValue(MouseOverBorderBrushProperty, value);
		}
		/// <summary>
		/// [附加属性] 鼠标移上时的边框画刷
		/// </summary>
		public static readonly DependencyProperty MouseOverBorderBrushProperty =
			DependencyProperty.RegisterAttached("MouseOverBorderBrush", typeof(Brush), typeof(RadioButtonAttached));
		#endregion

		#region [附加属性] 鼠标移上时的边框粗细(默认1)
		public static Thickness GetMouseOverBorderThickness(DependencyObject obj)
		{
			return (Thickness)obj.GetValue(MouseOverBorderThicknessProperty);
		}
		/// <summary>
		/// 设置 鼠标移上时的边框粗细(默认1)
		/// </summary>
		public static void SetMouseOverBorderThickness(DependencyObject obj, Thickness value)
		{
			obj.SetValue(MouseOverBorderThicknessProperty, value);
		}
		/// <summary>
		/// [附加属性] 鼠标移上时的边框粗细(默认1)
		/// </summary>
		public static readonly DependencyProperty MouseOverBorderThicknessProperty =
			DependencyProperty.RegisterAttached("MouseOverBorderThickness", typeof(Thickness), typeof(RadioButtonAttached), new PropertyMetadata(new Thickness(1)));
		#endregion

		#endregion
	}
}
